package web.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import common.LogCategory;

/**
 * @author orlin
 *
 */
public abstract class QueryPatternImpl implements QueryPattern {

	protected static final Logger log = LogCategory.getCategory(QueryPatternImpl.class);
	private List<QueryPatternImpl> subQueries = new ArrayList<QueryPatternImpl>();
	private QueryPatternImpl parentQuery;

	@Override
	public String getNickName() {
		int index = 0;
		List<QueryPatternImpl> queries = getParentQuery().getSubQueries();
		for (QueryPatternImpl query : queries) {
			//if (criteria.isJoin() || criteria.isTable()) 
			index++;
			if (this.equals(query)) {
				return getParentQuery().getNickName() + "_"+ index;
			}
		}
		return null;
	}

	final public QueryPatternImpl getParentQuery() {
		return parentQuery;
	}

	final public void setParentQuery(QueryPatternImpl parentQuery) {
		this.parentQuery = parentQuery;
	}
	
	final public List<QueryPatternImpl> getSubQueries() {
		List<QueryPatternImpl> subQueries = new ArrayList<QueryPatternImpl>();
		for (QueryPatternImpl obj: this.subQueries) {
			subQueries.add(obj);
		}
		return subQueries;
	}

	final public void addSubQueries(QueryPatternImpl... subQueries) {
		for (QueryPatternImpl subQuery: subQueries) {
			//addSubQuery(subQuery);
			this.subQueries.add(subQuery);
			subQuery.setParentQuery(this);
		}
	}

	@Override
	final public String getQueryText() {
		StringBuffer query = new StringBuffer();
		/** select */
		query.append(SELECT);
		query.append(getSelectClause());
		/** from */
		query.append(FROM);
		query.append(getFromClause());
		/** where */
		String whereClause = getWhereClause();
		if (0 < whereClause.length()) {
			query.append(WHERE);
			query.append(whereClause);
		}
		/** order by */
		String orderBy = getOrderByClause();
		if (0 < orderBy.length()) {
			query.append(ORDERBY);
			query.append(orderBy);
		}
		return query.toString();
	}

	/**
	 * when override this method add code:
	 * <code>
	 *	String selectClause = super.getSelectClause();
	 *	if ((null != selectClause) && (!selectClause.isEmpty())) {
	 *		result.append(QueryPattern.COMMA);
	 *		result.append(selectClause);
	 *	}
	 * </code>
	 */
	@Override
	public String getSelectClause() {
		StringBuffer result = new StringBuffer();
		for (QueryPatternImpl subQuery: subQueries) {
			String selectClause = subQuery.getSelectClause();
			if ((null != selectClause) && (!selectClause.isEmpty())) {
				if ((0 < result.length())) {
					result.append(COMMA);
				}
				result.append(selectClause);
			}
		}
		return result.toString();
	}

	/**
	 * when override this method add code:
	 * <code>
	 *	String fromClause = super.getFromClause();
	 *	if ((null != fromClause) && (!fromClause.isEmpty())) {
	 *		result.append(QueryPattern.COMMA);
	 *		result.append(fromClause);
	 *	}
	 * </code>
	 */
	@Override
	public String getFromClause() {
		StringBuffer result = new StringBuffer();
		for (QueryPatternImpl subQuery: subQueries) {
			String fromClause = subQuery.getFromClause();
			if ((null != fromClause) && (!fromClause.isEmpty())) {
				if ((0 < result.length())) {
					result.append(COMMA);
				}
				result.append(fromClause);
			}
		}
		return result.toString();
	}

	/**
	 * when override this method add code:
	 * <code>
	 *	String whereClause = super.getWhereClause();
	 *	if ((null != whereClause) && (!whereClause.isEmpty())) {
	 *		result.append(QueryPattern.AND);
	 *		result.append(whereClause);
	 *	}
	 * </code>
	 */
	@Override
	public String getWhereClause() {
		StringBuffer result = new StringBuffer();
		for (QueryPatternImpl subQuery: subQueries) {
			String whereClause = subQuery.getWhereClause();
			if ((null != whereClause) && (!whereClause.isEmpty())) {
				if ((0 < result.length())) {
					result.append(AND);
				}
				result.append(whereClause);
			}
		}
		return result.toString();
	}

	/**
	 * when override this method add code:
	 * <code>
	 *	String orderByClause = super.getOrderByClause();
	 *	if ((null != orderByClause) && (!orderByClause.isEmpty())) {
	 *		result.append(QueryPattern.COMMA);
	 *		result.append(orderByClause);
	 *	}
	 * </code>
	 */
	@Override
	public String getOrderByClause() {
		StringBuffer result = new StringBuffer();
		for (QueryPatternImpl subQuery: subQueries) {
			String orderByClause = subQuery.getOrderByClause();
			if ((null != orderByClause) && (!orderByClause.isEmpty())) {
				if ((0 < result.length())) {
					result.append(COMMA);
				}
				result.append(orderByClause);
			}
		}
		return result.toString();
	}

	/**
	 * when override this method add code:
	 * <code>
	 *	Map<String, Object> subParameters = super.getParameters();
	 *	if (null != subParameters) {
	 *		parameters.putAll(subParameters);
	 *	}
	 * </code>
	 */
	@Override
	public Map<String, Object> getParameters() {
		Map<String, Object> parameters = new HashMap<String, Object>(); 
		for (QueryPatternImpl subQuery: subQueries) {
			Map<String, Object> additionalParameters = subQuery.getParameters();
			if (null != additionalParameters) {
				parameters.putAll(additionalParameters);
			}
		}
		return parameters;
	}
}
